www.gusucode.com > VC++ 三维图形生成和察看工具 > VC++ 三维图形生成和察看工具/code/mesh/Lib3D/SceneGraph3d.cpp
//Download by http://www.NewXing.com //******************************************** // SceneGraph.cpp //******************************************** // class CSceneGraph //******************************************** // alliez@usc.edu // Created : 15/01/98 // Modified : 15/01/98 //******************************************** #include "stdafx.h" #include "Base3d.h" #include "SceneGraph3d.h" ////////////////////////////////////////////// // CONSTRUCTORS ////////////////////////////////////////////// //******************************************** // Constructor //******************************************** CSceneGraph3d::CSceneGraph3d() { m_pIndexTextureBinding = NULL; m_ListDone = 0; } //******************************************** // Destructor //******************************************** CSceneGraph3d::~CSceneGraph3d() { Free(); } //******************************************** // Destructor //******************************************** void CSceneGraph3d::Free(void) { // Textures if(m_ArrayTexture.GetSize()) { ::glDeleteTextures(m_ArrayTexture.GetSize(),m_pIndexTextureBinding); if(m_pIndexTextureBinding != NULL) { delete [] m_pIndexTextureBinding; m_pIndexTextureBinding = NULL; } } m_ArrayTexture.Free(); // Objects m_ArrayObject3d.Free(); } ////////////////////////////////////////////// // DATAS ////////////////////////////////////////////// //******************************************** // Add //******************************************** void CSceneGraph3d::Add(CObject3d *pObject3d) { m_ArrayObject3d.Add(pObject3d); } //******************************************** // Add //******************************************** void CSceneGraph3d::RemoveAt(int index) { m_ArrayObject3d.RemoveAt(index); } //******************************************** // GetAt //******************************************** CObject3d *CSceneGraph3d::GetAt(int index) { ASSERT(index < m_ArrayObject3d.GetSize()); return m_ArrayObject3d[index]; } //******************************************** // Operator [] //******************************************** CObject3d *CSceneGraph3d::operator[](int index) { ASSERT(index < m_ArrayObject3d.GetSize()); return m_ArrayObject3d[index]; } ////////////////////////////////////////////// // OPENGL ////////////////////////////////////////////// //******************************************** // BuildList //******************************************** int CSceneGraph3d::glBuildList() { TRACE("Build list"); // Meshes //*********************************** unsigned int size = m_ArrayObject3d.GetSize(); for(unsigned int i=0; i<size; i++) { CObject3d *pObject3d = m_ArrayObject3d.GetAt(i); if(pObject3d != NULL) { pObject3d->glBuildList(); TRACE("."); // progressing (debug mode) } } TRACE("ok\n"); // Textures //*********************************** unsigned int NbTexture = m_ArrayTexture.GetSize(); if(NbTexture) { TRACE("SceneGraph : texture binding...(%d texture(s))\n",NbTexture); // Cleanup if(m_pIndexTextureBinding != NULL) { ::glDeleteTextures(NbTexture,m_pIndexTextureBinding); delete [] m_pIndexTextureBinding; } m_pIndexTextureBinding = new unsigned int[NbTexture]; ::glGenTextures(NbTexture,m_pIndexTextureBinding); int error = glGetError(); ASSERT(error != GL_INVALID_VALUE); ASSERT(error != GL_INVALID_OPERATION); TRACE("Bind texture...\n"); for(i=0;i<NbTexture;i++) { while (GL_NO_ERROR != glGetError() ) {} // Bind texture glBindTexture(GL_TEXTURE_2D,m_pIndexTextureBinding[i]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); int error = glGetError(); ASSERT(error != GL_INVALID_ENUM); ASSERT(error != GL_INVALID_OPERATION); // Read datas CTexture *pTexture = m_ArrayTexture[i]; ASSERT(pTexture->GetData() != NULL); ::glTexImage2D(GL_TEXTURE_2D,0,3, pTexture->GetWidth(),pTexture->GetHeight(),0, GL_RGB,GL_UNSIGNED_BYTE,pTexture->GetData()); error = glGetError(); ASSERT(error != GL_INVALID_ENUM); ASSERT(error != GL_INVALID_OPERATION); ASSERT(error != GL_INVALID_VALUE); } } m_ListDone = 1; return 1; } //******************************************** // glDraw //******************************************** void CSceneGraph3d::glDraw(void) { if(!m_ListDone) glBuildList(); unsigned int size = m_ArrayObject3d.GetSize(); for(unsigned int i=0; i<size; i++) { CObject3d *pObject3d = m_ArrayObject3d[i]; // Texture if(pObject3d->GetType() == TYPE_MESH3D) { CMesh3d *pMesh = (CMesh3d *)pObject3d; int IndexTexture = pMesh->GetTextureIndex(); if(IndexTexture >= 0) { ASSERT(glIsTexture(m_pIndexTextureBinding[IndexTexture])); glBindTexture(GL_TEXTURE_2D,m_pIndexTextureBinding[IndexTexture]); TRACE("Texture : %d\n",m_pIndexTextureBinding[IndexTexture]); } // Drawing pObject3d->glDraw(); } else pObject3d->glDraw(); } } //******************************************** // glDraw //******************************************** void CSceneGraph3d::glDrawDirect(void) { unsigned int size = m_ArrayObject3d.GetSize(); for(unsigned int i=0; i<size; i++) { CObject3d *pObject3d = m_ArrayObject3d[i]; // Meshes if(pObject3d->GetType() == TYPE_MESH3D) { CMesh3d *pMesh = (CMesh3d *)pObject3d; pMesh->glDrawDirect(); } else pObject3d->glDraw(); } } //******************************************** // glDraw // draw only type //******************************************** void CSceneGraph3d::glDraw(int type) { if(!m_ListDone) glBuildList(); unsigned int size = m_ArrayObject3d.GetSize(); for(unsigned int i=0; i<size; i++) { CObject3d *pObject3d = m_ArrayObject3d[i]; if(pObject3d->GetType() == type) pObject3d->glDraw(); } } ////////////////////////////////////////////// // MISC ////////////////////////////////////////////// //******************************************** // BuildAdjacency // For each mesh //******************************************** int CSceneGraph3d::BuildAdjacency() { int size = m_ArrayObject3d.GetSize(); if(size ==0) return 0; TRACE("Scene %x : Start BuildAdjacency...\n",this); TRACE(" NbObject : %d\n",size); for(int i=0;i<size;i++) { CObject3d *pObject3d = m_ArrayObject3d[i]; if(pObject3d->GetType() != TYPE_MESH3D) continue; CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i]; pMesh->BuildAdjacency(); } TRACE("Scene %x : End BuildAdjacency...\n",this); return 1; } //******************************************** // CalculateNormalPerVertex // For each mesh //******************************************** int CSceneGraph3d::CalculateNormalPerVertex() { int size = m_ArrayObject3d.GetSize(); if(size ==0) return 0; for(int i=0;i<size;i++) { CObject3d *pObject3d = m_ArrayObject3d[i]; if(pObject3d->GetType() != TYPE_MESH3D) continue; CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i]; pMesh->CalculateNormalPerVertex(); } return 1; } //******************************************** // CalculateNormalPerFace // For each mesh //******************************************** int CSceneGraph3d::CalculateNormalPerFace() { int size = m_ArrayObject3d.GetSize(); if(size ==0) return 0; for(int i=0;i<size;i++) { CObject3d *pObject3d = m_ArrayObject3d[i]; if(pObject3d->GetType() != TYPE_MESH3D) continue; CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i]; pMesh->CalculateNormalPerFace(); } return 1; } //******************************************** // SetNormalBinding //******************************************** void CSceneGraph3d::SetNormalBinding(int type) { int size = m_ArrayObject3d.GetSize(); for(int i=0;i<size;i++) { CObject3d *pObject3d = m_ArrayObject3d[i]; if(pObject3d->GetType() != TYPE_MESH3D) continue; CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i]; pMesh->SetNormalBinding(type); } } //******************************************** // SetColorBinding //******************************************** void CSceneGraph3d::SetColorBinding(int type) { int size = m_ArrayObject3d.GetSize(); for(int i=0;i<size;i++) { CObject3d *pObject3d = m_ArrayObject3d[i]; if(pObject3d->GetType() != TYPE_MESH3D) continue; CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i]; pMesh->SetColorBinding(type); } } ////////////////////////////////////////////// // TEXTURES ////////////////////////////////////////////// //******************************************** // HasTexture //******************************************** int CSceneGraph3d::HasTexture(char *name, int *index) { for(int i=0;i<m_ArrayTexture.GetSize();i++) if(m_ArrayTexture[i]->GetFileName() == name) { *index = i; return 1; } return 0; } ////////////////////////////////////////////// // I/O ////////////////////////////////////////////// //******************************************** // SaveFile //******************************************** int CSceneGraph3d::SaveFile(char *name) { // Check if(NbObject() == 0) { AfxMessageBox("This scene does not contain meshes"); return 0; } // Check for valid file CStdioFile file; CFileException ex; // Write header if(!WriteHeader(file,name)) { AfxMessageBox("Error during writing header"); return 0; } // Meshes for(int i=0;i<NbObject();i++) { CObject3d *pObject = m_ArrayObject3d[i]; if(pObject->GetType() == TYPE_MESH3D) ((CMesh3d *)pObject)->WriteFile(file); } // Close file file.Close(); return 1; } //******************************************** // SaveFileRaw //******************************************** int CSceneGraph3d::SaveFileRaw(char *name) { // Check if(NbObject() == 0) { AfxMessageBox("This scene does not contain meshes"); return 0; } // Check for valid file CFile file; CFileException ex; // Try to open file (text mode) if(!file.Open(name,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary,&ex)) { #ifdef _DEBUG afxDump << "File could not be opened " << ex.m_cause << "\n"; #endif AfxMessageBox("Unable to open file for writing"); return 0; } // Meshes unsigned int NbMesh = NbObject(); file.Write(&NbMesh,sizeof(unsigned int)); for(unsigned int i=0;i<NbMesh;i++) { CObject3d *pObject = m_ArrayObject3d[i]; if(pObject->GetType() == TYPE_MESH3D) ((CMesh3d *)pObject)->WriteFileRaw(file); } // Close file file.Close(); return 1; } //********************************************** // WriteHeader // Do not close file //********************************************** int CSceneGraph3d::WriteHeader(CStdioFile &file, char *name) { CFileException ex; // Try to open file (text mode) if(!file.Open(name,CFile::modeCreate | CFile::modeWrite | CFile::typeText,&ex)) { #ifdef _DEBUG afxDump << "File could not be opened " << ex.m_cause << "\n"; #endif AfxMessageBox("Unable to open file for writing"); return 0; } // ** Header ******************************* TRACE("\nSave VRML 2.0 File...\n"); TRACE(" name : %s\n",name); TRY { file.WriteString("#VRML V2.0 utf8\n\n"); file.WriteString("# Produced by 3d Toolbox 1.0 (Pierre Alliez, CNET / DIH / HDM)\n\n"); } CATCH(CFileException, e) { #ifdef _DEBUG afxDump << "Error during writing " << e->m_cause << "\n"; #endif AfxMessageBox("Error during writing file header"); file.Close(); return 0; } END_CATCH // do not close file return 1; } // ** EOF **